﻿#include "vm/vm.h"
#include "vm/compiler.h"
#include "vm/debug.h"
#include "vm/table.h"
#include "vm/value.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
//没有这个,fabs要出错
#include <math.h>

#include "snprintf.h"
#include "..\my_trunc.h"
#include "utils.h"

#include "ds/dict.h"

static void runtime_error(const char *format, ...);
static VmBoolean is_falsey(Value value);

VM vm;

static void vm_stack_reset()
{
    vm.stackTop = vm.stack;
    vm.frameCount = 0;
}

static void vm_stack_push(Value value)
{
    *vm.stackTop = value;
    vm.stackTop++;
}

static Value vm_stack_pop()
{
    return *--vm.stackTop;
}

static Value vm_stack_peek(int distance)
{
    return vm.stackTop[-1 - distance];
}

static void runtime_error(const char *format, ...)
{
    int i ;
    va_list args;
    VmFunction *function = NULL;
    CallFrame *frame = NULL;
    size_t instruction;
    va_start(args, format);
    vfprintf(stderr, format, args);
    va_end(args);
    fputs("\n", stderr);
    for (i = vm.frameCount - 1; i >= 0; i--)
    {
        frame = &vm.frames[i];
        function = frame->function;
        // -1 because the IP is sitting on the next instruction to be
        // executed.
        instruction = frame->ip - function->chunk.code - 1;
        fprintf(stderr, "[line %d] in ", function->chunk.lines[instruction]);
        if (function->name == NULL)
        {
            fprintf(stderr, "script\n");
        }
        else
        {
            fprintf(stderr, "%s()\n", function->name->chars);
        }
    }
    vm_stack_reset();
}

static VmBoolean is_falsey(Value value)
{
    return IS_NIL(value) || (IS_BOOL(value) && !AS_BOOL(value));
}

static void vmstring_concatenate()
{
    VmString *b = AS_STRING(vm_stack_pop());
    VmString *a = AS_STRING(vm_stack_pop());
    VmString *result = NULL;
    size_t length = a->length + b->length;
    char *chars = (char *)alloc(length + 1);

    memcpy(chars, a->chars, a->length);
    memcpy(chars + a->length, b->chars, b->length);
    chars[length] = 0;

    result = vmstring_take(chars, length);
    vm_stack_push(object_val((VmObject *)result));
}

static int call(VmFunction *function, int argCount)
{
    CallFrame *frame;
    if (argCount != function->arity)
    {
        runtime_error("Expected %d arguments but got %d.", function->arity, argCount);
        return 0;
    }

    if (vm.frameCount == FRAMES_MAX)
    {
        runtime_error("Stack overflow.");
        return 0;
    }

    frame = &vm.frames[vm.frameCount++];
    frame->function = function;
    frame->ip = function->chunk.code;

    frame->slots = vm.stackTop - argCount - 1;
    return 1;
}

static void native_define(const char *name, NativeFn function)
{
    vm_stack_push(object_val((VmObject *)vmstring_copy(name, (int)strlen(name))));
    vm_stack_push(object_val((VmObject *)vmnative_new(function)));
    table_set(&vm.globals, AS_STRING(vm.stack[0]), vm.stack[1]);
    vm_stack_pop();
    vm_stack_pop();
}

int value_call(Value callable, int argCount)
{
    NativeFn native;
    Value result;

    if (IS_OBJECT(callable))
    {
        switch (OBJECT_TYPE(callable))
        {
        case OBJECT_FUNCTION:
            return call(AS_FUNCTION(callable), argCount);

        case OBJECT_NATIVE:
            native = AS_NATIVE(callable);
            result = native(argCount, vm.stackTop - argCount);
            vm.stackTop -= argCount + 1;
            vm_stack_push(result);
            return 1;
        default:
            // Non-callable object type.
            break;
        }
    }

    runtime_error("Can only call functions and classes.");
    return 0;
}

static Value native_clock(int argCount, Value *args)
{
    return number_val((double)clock() / CLOCKS_PER_SEC);
}
//steven+ (返回整数 )//参照
//0 VAL_BOOL  ,
//1 VAL_NIL   ,
//2 VAL_INT   ,   ////steven+
//3 VAL_UINT   ,  ////steven+
//4 VAL_NUMBER ,
//5 VAL_OBJECT
static Value native_type(int argCount, Value *args)
{
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
      bool_val(0);      
    }

    //return number_val(args[0].type);
    return integer2_val(args[0].type);
}

//整数和浮点数,浮点数和整数,比较大小,相差很小可以认为一样
int double_equal(double a ,double b)
{
    //double占8个字节，(c99)long double根据编译器实现不同，有占用8，10，12字节和16字节四种；
    double c=a-b;
    double d=fabs(c); 
    
    //printf("DEBUG | a=  %g  b= %g c= %g cmp= %g |\n",a,b,c ,d );
    if(d<0.00001)
        return 1;
    else
    return 0;
}

//==运算要值大小和累I型那个都相同,相似相等,用一个单独的函数来做,这个就是
static Value native_equal(int argCount, Value *args)
{
    Value a;
    Value b;
    long long int aa,bb;
    double aaa,bbb;
 
    
    //printf("DEBUG1");
    if(argCount<2)
    {
       //printf("DEBUG2");
        return bool_val(0);
    }
    a=args[0];
    b=args[1];
    
    //printf("DEBUG3");
    //布尔和int兼容
    if((a.type==VAL_BOOL||a.type==VAL_INT  ) && (b.type==VAL_BOOL||b.type==VAL_INT  ))
    {
       //printf("DEBUG4");
        if(a.type==VAL_BOOL)aa=AS_BOOL(a);
        if(a.type==VAL_INT) aa=AS_INTEGER(a);
        
        if(b.type==VAL_BOOL)bb=AS_BOOL(b);
        if(b.type==VAL_INT) bb=AS_INTEGER(b);
        
        return bool_val(aa==bb);
    }
    //printf("type %d %d ",a.type,b.type);
    //无符号和另外两个兼容的时候都转doube,好容纳3种类
    if((a.type==VAL_BOOL||a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
        && (b.type==VAL_BOOL||b.type==VAL_INT || b.type==VAL_UINT || b.type==VAL_NUMBER )
      )
    {
        //printf("DEBUG5");
        if(a.type==VAL_BOOL)  aaa=(double)AS_BOOL(a);
        if(a.type==VAL_INT)   aaa=(double)AS_INTEGER(a);
        if(a.type==VAL_UINT)  aaa=(double)AS_UINTEGER(a);
        if(a.type==VAL_NUMBER) aaa=(double)AS_NUMBER(a);
        
        
        if(b.type==VAL_BOOL)bbb=(double)AS_BOOL(b);
        if(b.type==VAL_INT) bbb=(double)AS_INTEGER(b);
        if(b.type==VAL_UINT) bbb=(double)AS_UINTEGER(b);
        if(b.type==VAL_NUMBER) bbb=(double)AS_NUMBER(b);
        
        return  bool_val(double_equal(aaa,bbb)==1);
    }
    //其他都是异常
    //printf("DEBUG6");
    return bool_val(0);
}

//整数1 整数2 布尔 浮点数 都可以转换成字符串
static Value native_tostr(int argCount, Value *args)
{
    Value a;
	char  str[50]={0};
    VmString* string ;
    
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
       string=vmstring_copy("", strlen(""));
       return   object_val((VmObject*)string);
    }
    a=args[0];
    if(IS_STRING(a))
        return a;
    if((a.type==VAL_BOOL||a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        //printf("DEBUG5");
        if(a.type==VAL_BOOL)  {  if(AS_BOOL(a)==1) memcpy(str,"true",4);else memcpy(str,"false",5); }
        if(a.type==VAL_INT)   {  my_snprintf(str,50,"%d",AS_INTEGER(a));                                  }
        if(a.type==VAL_UINT)  {  my_snprintf(str,50,"%llu",AS_UINTEGER(a));               }
        if(a.type==VAL_NUMBER){  my_snprintf(str,50,"%lf",AS_NUMBER(a))  ;                }
        
         string=vmstring_copy(str, strlen(str));
         return   object_val((VmObject*)string);
    }

        string=vmstring_copy("", strlen("")); 
      return   object_val((VmObject*)string); 
}

//支持整数,浮点数
static Value native_ceil(int argCount, Value *args)
{
    Value a;
//    char  str[50];
//    VmString* string ;
    
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
      return   integer2_val(0);
    }
    a=args[0];
    
    if((a.type==VAL_BOOL||a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        //printf("DEBUG5");
        if(a.type==VAL_BOOL)  { return   a ;}
        if(a.type==VAL_INT)   { return   a ;}
        if(a.type==VAL_UINT)  { return   a ;}
        if(a.type==VAL_NUMBER){ return   integer2_val((long long int )ceil(AS_NUMBER(a))); } 
    } 
     
      runtime_error("Not support type.");
      return   integer2_val(0);
    
}
static Value native_abs(int argCount, Value *args)
{
    Value a;
//    char  str[50];
//    VmString* string ;
    
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
      return   number_val(0);
    }
    a=args[0];
    
    if((/*a.type==VAL_BOOL||*/a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        //printf("DEBUG5");
        //if(a.type==VAL_BOOL)  { return   a ;}
        if(a.type==VAL_INT)   { return   integer2_val( llabs(AS_INTEGER(a)) ) ;} //longlong 是 llabs
        if(a.type==VAL_UINT)  { return   a ;}  //无符号数没有这个概念
        if(a.type==VAL_NUMBER){ return   number_val(fabs(AS_NUMBER(a))); } 
    } 
     
      runtime_error("Not support type.");
      return   integer2_val(0);
    
}

static Value native_acos(int argCount, Value *args)
{
    Value a;
//    char  str[50];
//    VmString* string ;
    
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
      return   number_val(0);
    }
    a=args[0];
    
    if((/*a.type==VAL_BOOL||*/a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        //printf("DEBUG5");
        //布尔不要 if(a.type==VAL_BOOL)  { return   a ;}
        if(a.type==VAL_INT)   { return   number_val(acos(AS_INTEGER(a)) ) ;}
        if(a.type==VAL_UINT)  { return   number_val(acos(AS_UINTEGER(a))); ;}  //无符号数没有这个概念
        if(a.type==VAL_NUMBER){ return   number_val(acos(AS_NUMBER(a))); } 
    } 
     
      runtime_error("Not support type.");
      return   number_val(0);
     
}


static Value native_asin(int argCount, Value *args)
{
    Value a;
//    char  str[50];
//    VmString* string ;
    
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
      return   number_val(0);
    }
    a=args[0];
    
    if((/*a.type==VAL_BOOL||*/a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        //printf("DEBUG5");
        //布尔不要 if(a.type==VAL_BOOL)  { return   a ;}
        if(a.type==VAL_INT)   { return   number_val(asin(AS_INTEGER(a)) ) ;}
        if(a.type==VAL_UINT)  { return   number_val(asin(AS_UINTEGER(a))); ;}  //无符号数没有这个概念
        if(a.type==VAL_NUMBER){ return   number_val(asin(AS_NUMBER(a))); } 
    } 
     
      runtime_error("Not support type.");
      return   number_val(0);
     
}


static Value native_atan(int argCount, Value *args)
{
    Value a;
//    char  str[50];
//    VmString* string ;
    
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
      return   number_val(0);
    }
    a=args[0];
    
    if((/*a.type==VAL_BOOL||*/a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        //printf("DEBUG5");
        //布尔不要 if(a.type==VAL_BOOL)  { return   a ;}
        if(a.type==VAL_INT)   { return   number_val(atan(AS_INTEGER(a)) ) ;}
        if(a.type==VAL_UINT)  { return   number_val(atan(AS_UINTEGER(a))); ;}  //无符号数没有这个概念
        if(a.type==VAL_NUMBER){ return   number_val(atan(AS_NUMBER(a))); } 
    } 
     
      runtime_error("Not support type.");
      return   number_val(0);
     
}

static Value native_atan2(int argCount, Value *args)
{
    Value a;
    Value b;
    double aa;
    double bb;
//    char  str[50];
//    VmString* string ;
    
    if(argCount<=1)
    {
      runtime_error("Need 2 argument.");
      return   number_val(0);
    }
    a=args[0];
    b=args[1];
    
    if((/*a.type==VAL_BOOL||*/a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
       &&(/*b.type==VAL_BOOL||*/b.type==VAL_INT || b.type==VAL_UINT || b.type==VAL_NUMBER ) 
      )
    {
        //printf("DEBUG5");
        //布尔不要 if(a.type==VAL_BOOL)  { return   a ;}
        if(a.type==VAL_INT)     aa=AS_INTEGER(a) ;
        if(a.type==VAL_UINT)    aa=AS_UINTEGER(a);
        if(a.type==VAL_NUMBER)  aa=AS_NUMBER(a)  ;
        
        if(b.type==VAL_INT)     bb=AS_INTEGER (b) ;
        if(b.type==VAL_UINT)    bb=AS_UINTEGER(b);
        if(b.type==VAL_NUMBER)  bb=AS_NUMBER  (b)  ;
        
         return   number_val(atan2(aa,bb)); 
        
    } 
     
      runtime_error("Not support type.");
      return   number_val(0);
     
}


static Value native_cos(int argCount, Value *args)
{
    Value a;
//    char  str[50];
//    VmString* string ;
    
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
      return   number_val(0);
    }
    a=args[0];
    
    if((/*a.type==VAL_BOOL||*/a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        //printf("DEBUG5");
        //布尔不要 if(a.type==VAL_BOOL)  { return   a ;}
        if(a.type==VAL_INT)   { return   number_val(cos(AS_INTEGER(a)) ) ;}
        if(a.type==VAL_UINT)  { return   number_val(cos(AS_UINTEGER(a))); ;}  //无符号数没有这个概念
        if(a.type==VAL_NUMBER){ return   number_val(cos(AS_NUMBER(a))); } 
    } 
     
      runtime_error("Not support type.");
      return   number_val(0);
     
}

/*
static Value native_deg(int argCount, Value *args)
{
    Value a;
    char  str[50];
    VmString* string ;
    
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
      return   number_val(0);
    }
    a=args[0];
    
    if((/*a.type==VAL_BOOL||* /a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        //printf("DEBUG5");
        //布尔不要 if(a.type==VAL_BOOL)  { return   a ;}
        if(a.type==VAL_INT)   { return   number_val(deg(AS_INTEGER(a)) ) ;}
        if(a.type==VAL_UINT)  { return   number_val(deg(AS_UINTEGER(a))); ;}  //无符号数没有这个概念
        if(a.type==VAL_NUMBER){ return   number_val(deg(AS_NUMBER(a))); } 
    } 
     
      runtime_error("Not support type.");
      return   number_val(0);
     
}
*/


static Value native_exp(int argCount, Value *args)
{
    Value a;
//    char  str[50];
//    VmString* string ;
    
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
      return   number_val(0);
    }
    a=args[0];
    
    if((/*a.type==VAL_BOOL||*/a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        //printf("DEBUG5");
        //布尔不要 if(a.type==VAL_BOOL)  { return   a ;}
        if(a.type==VAL_INT)   { return   number_val(exp(AS_INTEGER(a)) ) ;}
        if(a.type==VAL_UINT)  { return   number_val(exp(AS_UINTEGER(a))); ;}  //无符号数没有这个概念
        if(a.type==VAL_NUMBER){ return   number_val(exp(AS_NUMBER(a))); } 
    } 
     
      runtime_error("Not support type.");
      return   number_val(0);
     
}

static Value native_floor(int argCount, Value *args)
{
    Value a;
//    char  str[50];
///    VmString* string ;
    
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
      return   number_val(0);
    }
    a=args[0];
    
    if((/*a.type==VAL_BOOL||*/a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        //printf("DEBUG5");
        //布尔不要 if(a.type==VAL_BOOL)  { return   a ;}
        if(a.type==VAL_INT)   { return   number_val(floor(AS_INTEGER(a)) ) ;}
        if(a.type==VAL_UINT)  { return   number_val(floor(AS_UINTEGER(a))); ;}  //无符号数没有这个概念
        if(a.type==VAL_NUMBER){ return   number_val(floor(AS_NUMBER(a))); } 
    } 
     
      runtime_error("Not support type.");
      return   number_val(0);
     
}


static Value native_log(int argCount, Value *args)
{
    Value a;
//    char  str[50];
///    VmString* string ;
    
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
      return   number_val(0);
    }
    a=args[0];
    
    if((/*a.type==VAL_BOOL||*/a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        //printf("DEBUG5");
        //布尔不要 if(a.type==VAL_BOOL)  { return   a ;}
        if(a.type==VAL_INT)   { return   number_val(log(AS_INTEGER(a)) ) ;}
        if(a.type==VAL_UINT)  { return   number_val(log(AS_UINTEGER(a))); ;}  //无符号数没有这个概念
        if(a.type==VAL_NUMBER){ return   number_val(log(AS_NUMBER(a))); } 
    } 
     
      runtime_error("Not support type.");
      return   number_val(0);
     
}


static Value native_log10(int argCount, Value *args)
{
    Value a;
//    char  str[50];
//    VmString* string ;
    
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
      return   number_val(0);
    }
    a=args[0];
    
    if((/*a.type==VAL_BOOL||*/a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        //printf("DEBUG5");
        //布尔不要 if(a.type==VAL_BOOL)  { return   a ;}
        if(a.type==VAL_INT)   { return   number_val(log10(AS_INTEGER(a)) ) ;}
        if(a.type==VAL_UINT)  { return   number_val(log10(AS_UINTEGER(a))); ;}  //无符号数没有这个概念
        if(a.type==VAL_NUMBER){ return   number_val(log10(AS_NUMBER(a))); } 
    } 
     
      runtime_error("Not support type.");
      return   number_val(0);
     
}

/*
static Value native_rad(int argCount, Value *args)
{
    Value a;
    char  str[50];
    VmString* string ;
    
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
      return   number_val(0);
    }
    a=args[0];
    
    if((/*a.type==VAL_BOOL||* /a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        //printf("DEBUG5");
        //布尔不要 if(a.type==VAL_BOOL)  { return   a ;}
        if(a.type==VAL_INT)   { return   number_val(rad(AS_INTEGER(a)) ) ;}
        if(a.type==VAL_UINT)  { return   number_val(rad(AS_UINTEGER(a))); ;}  //无符号数没有这个概念
        if(a.type==VAL_NUMBER){ return   number_val(rad(AS_NUMBER(a))); } 
    } 
     
      runtime_error("Not support type.");
      return   number_val(0);
     
}
*/


static Value native_sin(int argCount, Value *args)
{
    Value a;
//    char  str[50];
//    VmString* string ;
    
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
      return   number_val(0);
    }
    a=args[0];
    
    if((/*a.type==VAL_BOOL||*/a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        //printf("DEBUG5");
        //布尔不要 if(a.type==VAL_BOOL)  { return   a ;}
        if(a.type==VAL_INT)   { return   number_val(sin(AS_INTEGER(a)) ) ;}
        if(a.type==VAL_UINT)  { return   number_val(sin(AS_UINTEGER(a))); ;}  //无符号数没有这个概念
        if(a.type==VAL_NUMBER){ return   number_val(sin(AS_NUMBER(a))); } 
    } 
     
      runtime_error("Not support type.");
      return   number_val(0);
     
}


static Value native_sqrt(int argCount, Value *args)
{
    Value a;
//    char  str[50];
//    VmString* string ;
    
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
      return   number_val(0);
    }
    a=args[0];
    
    if((/*a.type==VAL_BOOL||*/a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        //printf("DEBUG5");
        //布尔不要 if(a.type==VAL_BOOL)  { return   a ;}
        if(a.type==VAL_INT)   { return   number_val(sqrt(AS_INTEGER(a)) ) ;}
        if(a.type==VAL_UINT)  { return   number_val(sqrt(AS_UINTEGER(a))); ;}  //无符号数没有这个概念
        if(a.type==VAL_NUMBER){ return   number_val(sqrt(AS_NUMBER(a))); } 
    } 
     
      runtime_error("Not support type.");
      return   number_val(0);
     
}


static Value native_tan(int argCount, Value *args)
{
    Value a;
//    char  str[50];
//    VmString* string ;
    
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
      return   number_val(0);
    }
    a=args[0];
    
    if((/*a.type==VAL_BOOL||*/a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        //printf("DEBUG5");
        //布尔不要 if(a.type==VAL_BOOL)  { return   a ;}
        if(a.type==VAL_INT)   { return   number_val(tan(AS_INTEGER(a)) ) ;}
        if(a.type==VAL_UINT)  { return   number_val(tan(AS_UINTEGER(a))); ;}  //无符号数没有这个概念
        if(a.type==VAL_NUMBER){ return   number_val(tan(AS_NUMBER(a))); } 
    } 
     
      runtime_error("Not support type.");
      return   number_val(0);
     
}

//和rem不一样,rem函数是用trunc(截断) 这个是floor (地板)
static double mod(double a,double b)
{
   //BUG  double d=ceil(a / b);
    //bug double d=floor(a / b);
    double d=floor(a / b);
    double e=d  *b;
    double f=a - e;
    //printf("%g %g %g %g %g ",a,b,d,e,f);
    return f;
}

static Value native_mod(int argCount, Value *args)
{
    Value a,b;
//    char  str[50];
//    VmString* string ;
     double aa;
    double bb=0;
    
    if(argCount<=1)
    {
      runtime_error("Need 2 argument.");
      return   number_val(0);
    }
    a=args[0];
    b=args[1];
    
    if((/*a.type==VAL_BOOL||*/a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        if(a.type==VAL_INT)     aa=AS_INTEGER(a) ;
        if(a.type==VAL_UINT)    aa=AS_UINTEGER(a);
        if(a.type==VAL_NUMBER)  aa=AS_NUMBER(a)  ;
        
        if(b.type==VAL_INT)     bb=AS_INTEGER (b) ;
        if(b.type==VAL_UINT)    bb=AS_UINTEGER(b);
        if(b.type==VAL_NUMBER)  bb=AS_NUMBER  (b)  ;
        
         return   number_val( mod(aa , bb) ); 
        
    } 
     
      runtime_error("Not support type.");
      return   number_val(0);
     
}

//函数还有问题,取余数是向0靠拢,不是正无穷大,也不是负无穷大方向
static int64_t rem(int64_t a,int64_t b)
{
   //BUG  double d=ceil(a / b);
    //bug double d=floor(a / b);
    int64_t d=my_trunc(a / b);
    int64_t e=d  *b;
    int64_t f=a - e;
    //printf("%g %g %g %g %g ",a,b,d,e,f);
    return f;
}

static Value native_rem(int argCount, Value *args)
{
    Value a,b;
//    char  str[50];
//    VmString* string ;
    long long int aa;
    long long int bb=0;
//    unsigned long long int uaa;
//    unsigned long long int ubb;
    
    
    
    if(argCount<=1)
    {
      runtime_error("Need 2 argument.");
      return   integer2_val(0);
    }
    a=args[0];
    b=args[1];
    
   
    if((/*a.type==VAL_BOOL||*/a.type==VAL_INT || a.type==VAL_UINT || a.type==VAL_NUMBER ) 
      )
    {
        if(a.type==VAL_INT)     aa=AS_INTEGER(a) ;
        if(a.type==VAL_UINT)    aa=AS_UINTEGER(a);
        if(a.type==VAL_NUMBER)  aa=AS_NUMBER(a)  ;
        
        if(b.type==VAL_INT)     bb=AS_INTEGER (b) ;
        if(b.type==VAL_UINT)    bb=AS_UINTEGER(b);
        if(b.type==VAL_NUMBER)  bb=AS_NUMBER  (b)  ;
        
         return   number_val( rem(aa , bb) ); 
        
    } 
      runtime_error("Not support type.");
      return   integer2_val(0);
     
}

//参数 1字符串 2开始位置,3长度
static Value native_substr(int argCount, Value *args)
{
    Value a,b,c;
    VmString* string ;
    int start=0,len=0;
    
    if(argCount<=2)
    {
      runtime_error("Need 3 argument.");
       string=vmstring_copy("", strlen(""));
       return   object_val((VmObject*)string);
    }
    a=args[0];
    b=args[1];
    c=args[2];
    
    //不是字符串其实应该报告错误
    if(!IS_STRING(a))
    {
        string=vmstring_copy("", strlen(""));
       return   object_val((VmObject*)string);
    }
    
    if(b.type!= VAL_INT && b.type!=VAL_UINT && b.type!=VAL_NUMBER)
     {
        string=vmstring_copy("", strlen(""));
       return   object_val((VmObject*)string);
    }
    if(c.type!= VAL_INT && c.type!=VAL_UINT && c.type!=VAL_NUMBER)
     {
        string=vmstring_copy("", strlen(""));
       return   object_val((VmObject*)string);
    }

    
    if(b.type==VAL_INT ) start =AS_INTEGER(b);
    if( b.type==VAL_UINT) start =AS_UINTEGER(b);
    if( b.type==VAL_NUMBER) start =AS_NUMBER(b);
    
    if(c.type==VAL_INT ) len=AS_INTEGER(c);
    if( c.type==VAL_UINT) len=AS_UINTEGER(c);
    if( c.type==VAL_NUMBER) len =AS_NUMBER(c);
    
    //开始位置超过字符串长度
     if(len> AS_STRING( a)->length)len= AS_STRING( a)->length;
     
     if(start> AS_STRING( a)->length)start= AS_STRING( a)->length;
     
     //长度加开始位置超过原始长度
     if(start+len> AS_STRING( a)->length) len= AS_STRING( a)->length-start;
   
    
     string=vmstring_copy( AS_STRING( a)->chars + start ,  len);
         return   object_val((VmObject*)string);
}

//left
static Value native_leftstr(int argCount, Value *args)
{
    Value a,b,c;
    VmString* string ;
    int len=0;
    
    if(argCount<=1)
    {
      runtime_error("Need 2 argument.");
       string=vmstring_copy("", strlen(""));
       return   object_val((VmObject*)string);
    }
    a=args[0];
    b=args[1];

    //不是字符串其实应该报告错误
    if(!IS_STRING(a))
     {
        string=vmstring_copy("", strlen(""));
       return   object_val((VmObject*)string);
    }
    if(b.type!= VAL_INT && b.type!=VAL_UINT && b.type!=VAL_NUMBER)
     {
        string=vmstring_copy("", strlen(""));
       return   object_val((VmObject*)string);
    }
    if(b.type==VAL_INT ) len=AS_INTEGER(b);
    if( b.type==VAL_UINT) len=AS_UINTEGER(b);
    if( b.type==VAL_NUMBER) len =AS_NUMBER(b);
    
    //开始位置超过字符串长度
     if(len> AS_STRING( a)->length)len= AS_STRING( a)->length;
    
     //
     string=vmstring_copy( AS_STRING( a)->chars + 0 ,  len);
         return   object_val((VmObject*)string);
}
static Value native_rightstr(int argCount, Value *args)
{
    Value a,b,c;
    VmString* string ;
    int start,len=0;
    
    if(argCount<=1)
    {
      runtime_error("Need 2 argument.");
       string=vmstring_copy("", strlen(""));
       return   object_val((VmObject*)string);
    }
    a=args[0];
    b=args[1];

    //不是字符串其实应该报告错误
    if(!IS_STRING(a))
     {
        string=vmstring_copy("", strlen(""));
       return   object_val((VmObject*)string);
    }
    
    if(b.type!= VAL_INT && b.type!=VAL_UINT && b.type!=VAL_NUMBER)
     {
        string=vmstring_copy("", strlen(""));
       return   object_val((VmObject*)string);
    }
 
    if(b.type==VAL_INT ) len=AS_INTEGER(b);
    if( b.type==VAL_UINT) len=AS_UINTEGER(b);
    if( b.type==VAL_NUMBER) len =AS_NUMBER(b);
    
    //开始位置超过字符串长度
     if(len> AS_STRING( a)->length)len= AS_STRING( a)->length;
     start=  AS_STRING( a)->length - len;
     //
     string=vmstring_copy( AS_STRING( a)->chars + start ,  len);
         return   object_val((VmObject*)string);
}

static Value native_strlen(int argCount, Value *args)
{
    Value a ;
//    VmString* string ;
//    int start,
	 int len=0;
    
    if(argCount<=0)
    {
      runtime_error("Need 1 argument.");
       return   integer2_val(0);
    }
    a=args[0];
    //不是字符串其实应该报告错误
    if(!IS_STRING(a))
     {
       return   integer2_val(0);
    }
 
   return    integer2_val( AS_STRING( a)->length);
}


//字符串转整数
static Value native_strtoint(int argCount, Value *args)
{
    Value a ;
  //  VmString* string ;
    //int start,
		int len=0;
   // char *eptr;
    
    if(argCount<=0)
    {
      runtime_error("Need 1 argument.");
       return   integer2_val(0);
    }
    a=args[0];
    //不是字符串其实应该报告错误
    if(!IS_STRING(a))
     {
       return  integer2_val(0);
    }
    
    //AS_STRING( a)->chars
      
   return    integer2_val( my_atoll(AS_STRING( a)->chars ) ); //atol(  );
}
//u1 to bitstr,目标在后面,   
void unsigned_longlong_to_bit_string( unsigned long long int c ,unsigned char *bit_str)
{
	unsigned char c0 = 1;
	//static unsigned char bit_str[9] = {'\0'};
	int i;
	
	for(i=64; i>0; i--)
	{
		bit_str[i-1] = '0' + ((c&c0)?1:0);
		c0 += c0;
	}
	bit_str[64] = '\0';
	
	//return bit_str;
}
void signed_longlong_to_bit_string( signed long long int c ,unsigned char *bit_str)
{
	unsigned char c0 = 1;
	//static unsigned char bit_str[9] = {'\0'};
	int i;
	
	for(i=64; i>0; i--)
	{
		bit_str[i-1] = '0' + ((c&c0)?1:0);
		c0 += c0;
	}
	bit_str[64] = '\0';
	
	//return bit_str;
}
//有符号 无符号 两种数据转二进制
static Value native_tobinstr(int argCount, Value *args)
{
    Value a;
    char  str[65];
    VmString* string ;
    
    if(argCount<=0)
    {
      runtime_error("Need none argument.");
       string=vmstring_copy("", strlen(""));
       return   object_val((VmObject*)string);
    }
    a=args[0];
 
    if((a.type==VAL_INT || a.type==VAL_UINT ) 
      )
    {

        if(a.type==VAL_INT)   {  signed_longlong_to_bit_string(AS_INTEGER(a),str);            }
        if(a.type==VAL_UINT)  {  unsigned_longlong_to_bit_string(AS_UINTEGER(a),str);  }
    
        
         string=vmstring_copy(str, strlen(str));
         return   object_val((VmObject*)string);
    }

   string=vmstring_copy("", strlen("")); 
   return   object_val((VmObject*)string); 
}

//支持1维,2维数组,1维数,例子 var a=array(i1_2,i1_10) 其中1代表1维,2代表2字节整数,10代表数量,10个元素
//2维数,例子 var a=array(i1_4,i1_10,i1_20) 其中2代表2维,4代表4字节整数,10代表数量,10个元素
//用参数个数,2个参数是1d,3个参数是2d
//干脆用  var a=array("2d","int",10) 更加明确,但是最好是做成常量,
//目前支持1-3维 
static Value native_array(int argCount, Value *args)
{
    Value a;
    Value ww[4];
    VmArray* data ;
    
    if(argCount<=1)
    {
       runtime_error("Need 2,3 argument.");
       return  nil_val() ;
    }
    a=args[0];
    ww[0]=args[1];
    if(argCount>=3)ww[1]=args[2];
    if(argCount>=4)ww[2]=args[3];
 
   //printf(" %d %d %d ",argCount  , a.type ,ww[0].type);
 
   if(
      (argCount==2 && a.type==VAL_INT && ww[0].type==VAL_INT ) 
   || (argCount==3 && a.type==VAL_INT && ww[0].type==VAL_INT && ww[1].type==VAL_INT ) 
   || (argCount==4 && a.type==VAL_INT && ww[0].type==VAL_INT && ww[1].type==VAL_INT && ww[2].type==VAL_INT ) 
     )
   {
       //printf("DEBUG 2 ");
       data=(VmArray*)malloc(sizeof(VmArray));
	   if(data==NULL)
       {
         runtime_error("Malloc faile.");
         return  nil_val() ;
       }
       data->wd=argCount-1;//是几维的
       data->w[0]=data->w[1]=data->w[2]=data->w[3]=0;//初始化
       data->w[0]=AS_INTEGER(ww[0]);
       data->w[1]=AS_INTEGER(ww[1]);
       data->w[2]=AS_INTEGER(ww[2]);
       //printf("wd =%d",data->wd);
       data->object.type=OBJECT_ARRAY;
       data->length= ((data->w[0]>0)?data->w[0]:1) 
                     * ((data->w[1]>0)?data->w[1]:1) 
                     * ((data->w[2]>0)?data->w[2]:1) ;//3维数组,如果维大于0才计入
      //printf("DEBUGsubtype param0 type=%d \n",AS_INTEGER(a));              
                     
       if(AS_INTEGER(a)==1 ){ data->data=(int8_t *) malloc(data->length*sizeof(int8_t ));  data->subtype=1 ;       }
       if(AS_INTEGER(a)==2 ){ data->data=(int16_t*) malloc(data->length*sizeof(int16_t));  data->subtype=2 ;       }
       if(AS_INTEGER(a)==4 ){ data->data=(int32_t*) malloc(data->length*sizeof(int32_t));  data->subtype=4 ;       }
       if(AS_INTEGER(a)==8 ){ data->data=(int64_t*) malloc(data->length*sizeof(int64_t));  data->subtype=8 ;       }
                                                                                                                
       if(AS_INTEGER(a)==11){ data->data=(uint8_t *)malloc(data->length*sizeof(uint8_t )); data->subtype=11;       }
       if(AS_INTEGER(a)==12){ data->data=(uint16_t*)malloc(data->length*sizeof(uint16_t)); data->subtype=12;       }
       if(AS_INTEGER(a)==14){ data->data=(uint32_t*)malloc(data->length*sizeof(uint32_t)); data->subtype=14;       }
       if(AS_INTEGER(a)==18){ data->data=(uint64_t*)malloc(data->length*sizeof(uint64_t)); data->subtype=18;       }
                                                                                                                
       if(AS_INTEGER(a)==21){ data->data=(float *)  malloc(data->length*sizeof(float ));   data->subtype=21;       }
       if(AS_INTEGER(a)==22){ data->data=(double*)  malloc(data->length*sizeof(double));   data->subtype=22;       }
 
       return   object_val((VmObject*)data);
   }else {
       runtime_error("param err.");
       return  nil_val() ;
    }
 
}

//从数组取,参数个数 2,3,4
//2个参数是1维数组,例如 array_get(a,1) 取第2(0开始)的元素
static Value native_array_get(int argCount, Value *args)
{
    Value a,ww[4];
 
//    VmArray* data ;
    int8_t *   pint8    ;
    int16_t*   pint16   ;
    int32_t*   pint32   ;
    int64_t*   pint64   ;
    uint8_t *  upint8   ;
    uint16_t*  upint16  ;
    uint32_t*  upint32  ;
    uint64_t*  upint64  ;
    float*     pfloat   ;
    double*    pdouble  ;
    int wdt;
    int wi;
    int w[4];
   
   if(argCount<=1)
    {
       runtime_error("Need 3 or 4 argument.");
       return  nil_val() ;
    }
    wdt=argCount-1;//几维
    a=args[0];//array变量
    if(wdt!=AS_ARRAY(a)->wd)
    {
       runtime_error("Error ,target wd=%d  .",AS_ARRAY(a)->wd);
       return  nil_val() ;
    }
    
    //最大3个坐标  
    for(wi=1;wi<=argCount-1;wi++)
    {
      w[wi-1]=AS_INTEGER(args[wi]);
      ww[wi-1]=args[wi];
    }
 
    //printf("DEBUGd %d  %d    %d    %d \n",argCount,IS_ARRAY(a),ww[0].type==VAL_INT,ww[0].type );
    if(
      (argCount==2 && IS_ARRAY(a)   && ww[0].type==VAL_INT    ) 
      ||(argCount==3 && IS_ARRAY(a) && ww[0].type==VAL_INT && ww[1].type==VAL_INT    ) 
      ||(argCount==4 && IS_ARRAY(a) && ww[0].type==VAL_INT && ww[1].type==VAL_INT &&ww[2].type==VAL_INT   )
      )      
    {
       if( (  argCount==2 && (   w[0]   >= AS_ARRAY(a)->w[0] ||  w[0]  < 0))
           ||(argCount==3 && (   w[0]   >= AS_ARRAY(a)->w[0] ||  w[0]  < 0  
                             ||  w[1]   >= AS_ARRAY(a)->w[1] ||  w[1]  < 0))
           ||(argCount==4 && (   w[0]   >= AS_ARRAY(a)->w[0] ||  w[0]  < 0
                             ||  w[1]   >= AS_ARRAY(a)->w[1] ||  w[1]  < 0
                             ||  w[2]   >= AS_ARRAY(a)->w[2] ||  w[2]  < 0
                             )
              )
         ) 
       {
         runtime_error("Error argument 2 ,out of bound.");
         return  nil_val() ;  
       }else
       {
           //坐标 3x3x3数组举例, 1,1,1坐标为  
           //所以应该 3*1*3+3*1+1=13           
           int p;
           if(argCount==4)  p=AS_ARRAY(a)->w[0]*AS_ARRAY(a)->w[1] *  (w[0])
                +AS_ARRAY(a)->w[1]* (w[1]) 
                + (w[2]);
           if(argCount==3)  p=AS_ARRAY(a)->w[0] *  (w[0]) 
                + (w[1]);
           if(argCount==2)  p= (w[0]);
           
          //printf("DEBUGD type=%d p=%d \n",AS_ARRAY(a)->subtype,p);
           
           if(AS_ARRAY(a)->subtype==1 ){ pint8   =(int8_t   *)AS_ARRAY(a)->data ;pint8   =pint8   + p;   return integer2_val(*pint8  );  }
           else if(AS_ARRAY(a)->subtype==2 ){ pint16  =(int16_t  *)AS_ARRAY(a)->data ;pint16  =pint16  + p;   return integer2_val(*pint16 );  }
           else if(AS_ARRAY(a)->subtype==4 ){ pint32  =(int32_t  *)AS_ARRAY(a)->data ;pint32  =pint32  + p;   return integer2_val(*pint32 );  }
           else if(AS_ARRAY(a)->subtype==8 ){ pint64  =(int64_t  *)AS_ARRAY(a)->data ;pint64  =pint64  + p;   return integer2_val(*pint64 );  }
           else if(AS_ARRAY(a)->subtype==11){ upint8  =(uint8_t   *)AS_ARRAY(a)->data ;upint8  =upint8  + p;   return uinteger2_val(*upint8 );  }
           else if(AS_ARRAY(a)->subtype==12){ upint16 =(uint16_t  *)AS_ARRAY(a)->data ;upint16 =upint16 + p;   return uinteger2_val(*upint16);  }
           else if(AS_ARRAY(a)->subtype==14){ upint32 =(uint32_t  *)AS_ARRAY(a)->data ;upint32 =upint32 + p;   return uinteger2_val(*upint32);  }
           else if(AS_ARRAY(a)->subtype==18){ upint64 =(uint64_t  *)AS_ARRAY(a)->data ;upint64 =upint64 + p;   return uinteger2_val(*upint64);  }
           else if(AS_ARRAY(a)->subtype==21){ pfloat  =(float    *)AS_ARRAY(a)->data ;pfloat  =pfloat  + p;   return number_val (*pfloat );   }
           else if(AS_ARRAY(a)->subtype==24){ pdouble =(double   *)AS_ARRAY(a)->data ;pdouble =pdouble + p;   return number_val (*pdouble);  }
           else  return  nil_val() ;
       }
    }
    else{
       runtime_error("argument error.");
       return  nil_val() ;
    }
 
}

//数组元素赋值,例子 array_set(a,1,123) 一维数组 元素下标1(第2个元素)赋值123
//最大支持3维       array_set(a,1,2,123)  2维数组 元素下标1,2(第2行,3列元素)赋值123
//                  array_set(a,1,2,3,123)  3维数组 元素下标1,2(第2页,3行 ,4列元素)赋值123
static Value native_array_set(int argCount, Value *args)
{
    Value a,val;
   // VmArray* data ;
    int8_t *   pint8    ;
    int16_t*   pint16   ;
    int32_t*   pint32   ;
    int64_t*   pint64   ;
    uint8_t *  upint8   ;
    uint16_t*  upint16  ;
    uint32_t*  upint32  ;
    uint64_t*  upint64  ;
    float*     pfloat   ;
    double*    pdouble  ;
    int wi;
    int w[4];
    Value ww[4];
    int wdt;
    
    if(argCount<=2)
    {
       runtime_error("Need 3 or 4 argument.");
       return  nil_val() ;
    }
    wdt=argCount-2;//几维
    a=args[0];//array变量
    if(wdt!=AS_ARRAY(a)->wd)
    {
       runtime_error("Error ,target wd=%d  .",AS_ARRAY(a)->wd);
       return  nil_val() ;
    }
    
    val=args[argCount-1]; //最后是值
    //最大3个坐标  
    for(wi=1;wi<=argCount-2;wi++)
    {
      w[wi-1]=AS_INTEGER(args[wi]);
      ww[wi-1]= args[wi];
    }
  
    //printf("DEBUGOVER  argCount= %d  w0= %d  arrayw0=%d \n",argCount ,w[0],AS_ARRAY(a)->w[0]  );
    if(
      (argCount==3 && IS_ARRAY(a)   && ww[0].type==VAL_INT    ) 
      ||(argCount==4 && IS_ARRAY(a) && ww[0].type==VAL_INT && ww[1].type==VAL_INT    ) 
      ||(argCount==5 && IS_ARRAY(a) && ww[0].type==VAL_INT && ww[1].type==VAL_INT &&ww[2].type==VAL_INT   )
      )      
    {
       if( (argCount==3 &&   (w[0]   >= AS_ARRAY(a)->w[0] ||  w[0]  < 0))
           ||(argCount==4 && (w[0]   >= AS_ARRAY(a)->w[0] ||  w[0]  < 0
                           || w[1]   >= AS_ARRAY(a)->w[1] ||  w[1]  < 0))
           ||(argCount==5 && (w[0]   >= AS_ARRAY(a)->w[0] ||  w[0]  < 0
                           || w[1]   >= AS_ARRAY(a)->w[1] ||  w[1]  < 0
                           || w[2]   >= AS_ARRAY(a)->w[2] ||  w[2]  < 0
                           )
              )
         ) 
       {
         runtime_error("Error argument 2 ,out of bound.");
         return  nil_val() ;  
       }else
       {
           //坐标 3x3x3数组举例, 1,1,1坐标为  
           //所以应该 3*1*3+3*1+1=13           
           int p;
           if(argCount==5)  p=AS_ARRAY(a)->w[0]*AS_ARRAY(a)->w[1] *  (w[0])
                +AS_ARRAY(a)->w[1]* (w[1]) 
                + (w[2]);
           if(argCount==4)  p=AS_ARRAY(a)->w[0] *  (w[0]) 
                + (w[1]);
           if(argCount==3)  p= (w[0]);
           
           //printf("DEBUGD p=%d ",p);
                    
          //printf("DEBUGset datatype=%d %d",AS_ARRAY(a)->subtype,p);
           if(AS_ARRAY(a)->subtype==1 ){ pint8   =(int8_t   *)AS_ARRAY(a)->data ;pint8   =pint8   + p; *pint8   =AS_INTEGER(val);   return bool_val(1); }
           else if(AS_ARRAY(a)->subtype==2 ){ pint16  =(int16_t  *)AS_ARRAY(a)->data ;pint16  =pint16  + p; *pint16  =AS_INTEGER(val);   return bool_val(1); }
           else if(AS_ARRAY(a)->subtype==4 ){ pint32  =(int32_t  *)AS_ARRAY(a)->data ;pint32  =pint32  + p; *pint32  =AS_INTEGER(val);   return bool_val(1); }
           else if(AS_ARRAY(a)->subtype==8 ){ pint64  =(int64_t  *)AS_ARRAY(a)->data ;pint64  =pint64  + p; *pint64  =AS_INTEGER(val);   return bool_val(1); }
           else if(AS_ARRAY(a)->subtype==11){ upint8  =(uint8_t   *)AS_ARRAY(a)->data ;upint8  =upint8  + p; *upint8  =AS_UINTEGER(val);  return bool_val(1);  }
           else if(AS_ARRAY(a)->subtype==12){ upint16 =(uint16_t  *)AS_ARRAY(a)->data ;upint16 =upint16 + p; *upint16 =AS_UINTEGER(val);  return bool_val(1);  }
           else if(AS_ARRAY(a)->subtype==14){ upint32 =(uint32_t  *)AS_ARRAY(a)->data ;upint32 =upint32 + p; *upint32 =AS_UINTEGER(val);  return bool_val(1);  }
           else if(AS_ARRAY(a)->subtype==18){ upint64 =(uint64_t  *)AS_ARRAY(a)->data ;upint64 =upint64 + p; *upint64 =AS_UINTEGER(val);  return bool_val(1);  }
           else if(AS_ARRAY(a)->subtype==21){ pfloat  =(float    *)AS_ARRAY(a)->data ;pfloat  =pfloat  + p; *pfloat  =AS_NUMBER(val);    return bool_val(1); }
           else if(AS_ARRAY(a)->subtype==24){ pdouble =(double   *)AS_ARRAY(a)->data ;pdouble =pdouble + p; *pdouble =AS_NUMBER(val);    return bool_val(1);}
            return  nil_val() ;
       }
    }
    else{
       runtime_error("argument error.");
       return  nil_val() ;
    }
}

//返回数组元素个数,针对一维数组,是数组就返回长度,否则返回0
//所以数组要求不要是0长度的
static Value native_array_len(int argCount, Value *args)
{
    Value a;
    int ww=0;
    
    if(argCount<=0)
    {
       runtime_error("Need 1 argument.");
       return  nil_val() ;
    }
    a=args[0];//array变量
    
    //printf("DEBUG %d %d ",IS_ARRAY(a),AS_ARRAY(a)->wd);
    if(IS_ARRAY(a) && AS_ARRAY(a)->wd==1)ww=AS_ARRAY(a)->w[0];
    if(IS_ARRAY(a) && AS_ARRAY(a)->wd==2)ww=AS_ARRAY(a)->w[0]*AS_ARRAY(a)->w[1];
    if(IS_ARRAY(a) && AS_ARRAY(a)->wd==3)ww=AS_ARRAY(a)->w[0]*AS_ARRAY(a)->w[1]*AS_ARRAY(a)->w[2];
    
       
    return integer2_val(ww);
    
}

//MAP系列
//哈希桶大小修改成动态的
static unsigned int hash_code(const char* key,int cap)
{
    unsigned int hash = 0, i = 0;
    size_t length = strlen(key);
    for (i = 0; i < length; i++) {
        hash = 31 * hash + key[i];
    }
    //return hash %  DICT_INITIAL_CAPACITY;
    return hash %  cap;
}

static KeyValuePair* map_get_bucket(VmMap* map, const char* key)
{
    KeyValuePair* bucket = NULL;
    int hash = 0;
    if (map == NULL || map->count == 0) {
        return NULL;
    }
    //hash = hash_code(key);
    hash = hash_code(key,map->capacity); //map 不用AS_MAP Value才需要
    for (bucket = map->buckets[hash]; bucket != NULL; bucket = bucket->next) 
    {
		  if(bucket==NULL)return NULL;//bug
        if(bucket->key==NULL)return NULL;//bug
        if (strcmp(key, bucket->key) == 0) {
            return bucket;
        }
    }
    return NULL;
}


static Value  native_map(int argCount, Value *args)
{
    VmMap* map = (VmMap*)alloc(sizeof(VmMap));
    memset(map, 0, sizeof(VmMap));
    map->capacity = DICT_INITIAL_CAPACITY;
    map->count = 0;
    //bug
    map->object.type=OBJECT_MAP;
    //map=(VmMap*)malloc(sizeof(VmMap));
    //指针数组,16个元素,64位系统 128byte
    map->buckets=(KeyValuePair**)alloc(sizeof(KeyValuePair*)*map->capacity);
    //printf("DEBUG %d size1  %d ",sizeof(KeyValuePair*)*map->capacity,sizeof(KeyValuePair*));
    //指针初始化
	memset(map->buckets,0,sizeof(KeyValuePair*)*map->capacity);//sizeof(map->buckets));//bug
    
   return   object_val((VmObject*)map);
}


static int map_contains(VmMap* map, const char* key)
{
    return map_get_bucket(map, key) != NULL;
}

//扩容
static int map_resize(VmMap* map)
{
    KeyValuePair** new_buckets ;
     KeyValuePair *nextBucket=NULL;//[DICT_INITIAL_CAPACITY];
     KeyValuePair *bucket=NULL,*tempbucket_next=NULL;
     KeyValuePair *prevBucket=NULL;
    int newsize=map->capacity*2;//扩容一倍 //AS_MAP(map) --
    int i,newhash;
    new_buckets=(KeyValuePair**)malloc(sizeof(KeyValuePair*)*newsize);
	memset(new_buckets,0,sizeof(KeyValuePair*)*newsize);

    if(new_buckets==NULL)//如果分配内存失败,就不扩容
      return 0;
    //成功就复制原先的老的数据到新的桶链表里面
    //for(i=0;i<map->capacity;i++)
	for(i=0;i<map->capacity;i++)
    {
      bucket = map->buckets[i];
	  //BUG tempbucket_next=bucket->next;
	  tempbucket_next=(bucket!=NULL)?bucket->next:NULL;
      for (; bucket != NULL; bucket =tempbucket_next)// bucket->next) 
      {
		  if(bucket->key!=NULL)
		  {
		  // tempbucket=bucket;      //BUG
		  // tempbucket->next=NULL;  //BUG 要用一个临时指针来复制原先的元素(有可能next有数据,所以只复制单个节点,尾巴去掉),要重新hash所有元素

		   tempbucket_next=bucket->next;  //保存下一个   
		   bucket->next=NULL;

           newhash=hash_code(bucket->key,newsize);

           prevBucket = new_buckets[newhash];//老数据插入到新桶的头节点
           new_buckets[newhash]=bucket;  //复制数据(指针)
           new_buckets[newhash]->next=prevBucket;//上次的头接到这个后面
		    
		  }
      }
    }
    //复制完毕,释放老buckets
	/*
    for (i = 0; i <map->capacity;i++)// DICT_INITIAL_CAPACITY; i++) 
    {
        nextBucket = bucket = map->buckets[i];
        while (bucket != NULL) 
        {
            fr(bucket->value);
            fr(bucket->key);
            nextBucket = bucket->next;
    	    //BUG fr(bucket);
            bucket = nextBucket;
        }
    }
	*/
	//bug只能释放桶本身,其他元素都不能释放,包括第一个元素指向的内容
	fr(map->buckets);//
    //指向新的
    map->buckets=new_buckets;
	//容量也要写
	map->capacity=newsize;
   return 1;
}

//int  native_map_add(VmMap* map, const char* key, void* value);
static Value native_map_add(int argCount, Value *args)
{
    KeyValuePair *pair = NULL, *bucket = NULL;
    int hash = 0;
    Value map, keyv,valv;
    char* key;
       
   if(argCount<=2)
    {
       runtime_error("Need 3 argument.");
       return  nil_val() ;
    }
    map=args[0];//map变量
    keyv=args[1];// 
    valv=args[2];// 
   
    if(!IS_MAP(map) || !IS_STRING(keyv))
    {
       runtime_error("Error ,arguments must be map,stringkey ,value");
       return  bool_val(0);  
    }
    key=AS_STRING(keyv )->chars;


    if (!map_contains(AS_MAP(map), key)) 
    {
            
        //我假设元素个数已经达到初始值16的4倍的时候进行扩容,扩到原有的2倍
        if( (AS_MAP(map)->count+1) >(AS_MAP(map)->capacity*4) )
        {
            map_resize(AS_MAP(map));
           //printf("DEBUG 扩容");
        }
        //printf("DEBUG 正常add %d %d\n",AS_MAP(map)->capacity,AS_MAP(map)->count);
        pair = (KeyValuePair*)alloc(sizeof(KeyValuePair));
        pair->key = (char*)clone((void*)key, strlen(key) + 1);
        //pair->value = (void*)&valv;//clone(&valv,sizeof(valv));  //这里要不要clone,局部变量克隆出去
        //bug
        pair->value = (void*)clone(&valv,sizeof(valv)); 
        
       //printf("DEBUG %d\n", AS_INTEGER((*(Value*)pair->value)));
        
        pair->next = NULL;
        hash = hash_code(key,AS_MAP(map)->capacity);
        bucket = AS_MAP(map)->buckets[hash];
        if (bucket == NULL) {
            AS_MAP(map)->buckets[hash] = pair;
        } else {
            pair->next = AS_MAP(map)->buckets[hash];
            AS_MAP(map)->buckets[hash] = pair;
        }
        AS_MAP(map)->count++;
        return  bool_val(1);
    }
    return  bool_val(0);
}
    
    
//int  native_map_remove(VmMap* map, const char* key);

static Value native_map_remove(int argCount, Value *args)
{ 

    KeyValuePair *bucket = NULL,*bucket_head=NULL, *prevBucket = NULL;
    int hash = 0;//
     Value map, keyv;
    char* key;

   if(argCount<=1)//TO
    {
       runtime_error("Need 2 argument.");
       return  nil_val() ;
    }
    map=args[0];//map变量
    keyv=args[1];// 
    
    if(!IS_MAP(map) || !IS_STRING(keyv))
    {
       runtime_error("argument 0 must be map var, argument 1 must be string.");
       return  nil_val() ;
    }
    //printf("DEBUG1\n");
    key=AS_STRING(keyv)->chars;
    ///printf("DEBUG2\n");
    hash=hash_code(key,AS_MAP(map)->capacity);
    //printf("DEBUG3\n");
    bucket = AS_MAP(map)->buckets[hash];
    //printf("DEBUG4\n");
    if (bucket != NULL) 
	{
        //printf("DEBUG5\n");
        for (bucket_head=bucket = AS_MAP(map)->buckets[hash]; bucket != NULL; bucket = bucket->next) 
		{
            //printf("DEBUG6\n");
			 prevBucket = bucket;
            if (strcmp(key, bucket->key) == 0) 
			{
                //printf("DEBUG7 %x \n",bucket->value);
                bucket->value=NULL;//DeleteValue(bucket);
                
                //printf("DEBUG8 %x \n",bucket->key);
                
                fr(bucket->key);
				bucket->key=NULL;//bug
                prevBucket->next = bucket->next;
                
                //printf("DEBUG9 %x \n",bucket);
                //BUG bucket本身是 buckets数组元素的指针 fr(bucket);
                //桶元素可不能释放
                if(bucket_head!=bucket)
					fr(bucket);
                bucket=NULL;//BUG
                //printf("DEBUG10");
                return bool_val(1);
            }
 
        }
    }
    //printf("DEBUG11");
    return bool_val(0);
}


//void native_map_destroy(VmMap* map);
//static Value native_map_destroy(int argCount, Value *args)
//{ 
//
//    KeyValuePair *bucket = NULL, *nextBucket = NULL;
//    int hash = 0;//
//    Value map;//, keyv,valv;
//    //char* key;
//        int i = 0;
//     
//     //printf("DEBUG11");
//   if(argCount<=0)
//    {
//       runtime_error("Need 1 argument.");
//       return  nil_val() ;
//    }
//    //printf("DEBUG12");
//    map=args[0];//map变量
//    
//    //printf("DEBUG13");
//     if(!IS_MAP(map)  )
//    {
//       //printf("DEBUG15");
//       runtime_error("argument 0 must be map var .");
//       return  nil_val() ;
//    }
//    
//    //printf("DEBUG16");
//    for (i = 0; i < DICT_INITIAL_CAPACITY; i++) 
//    {
//        //printf("DEBUG17");
//        nextBucket = bucket = AS_MAP(map)->buckets[i];
//        while (bucket != NULL) 
//        {
//            //printf("DEBUG18");
//            //AS_MAP(->DeleteValue(bucket);
//            bucket->value=NULL;
//            //printf("DEBUG19");
//            fr(bucket->key);
//            //printf("DEBUG20");
//            nextBucket = bucket->next;
//            //printf("DEBUG21");
//            //BUG 
//			fr(bucket);
//            //printf("DEBUG22");
//            bucket = nextBucket;
//            //printf("DEBUG23");
//        }
//    }
//    //printf("DEBUG24");
//    fr(AS_MAP(map));
//    //printf("DEBUG25");
//    return bool_val(1);
//}

 

//void*native_map_get(VmMap* map, const char* key);
static Value native_map_get(int argCount, Value *args)
{ 

    KeyValuePair *bucket = NULL ;
    int hash = 0;//
    Value map, keyv,valv;
    char* key;

   if(argCount<=1)
    {
       runtime_error("Need 2 argument.");
       return  nil_val() ;
    }
    
    map=args[0];//map变量
    keyv=args[1];//
    
    //
    //printf("DEBUG %x\n",map);
    
    if(!IS_MAP(map) || !IS_STRING(keyv))
    {
       runtime_error("argument 0 must be map var, argument 1 must be string.");
       return  nil_val() ;
    }
    
    key=AS_STRING(keyv)->chars;

    bucket = map_get_bucket(AS_MAP(map), key);
    if( bucket != NULL )
    {
        valv=*(Value*)(bucket->value) ;//知识点 将void指针转换成 Value指针,再解引用,并且局部分配之后返回
        return valv;
    }
    else  return  nil_val() ;
}
//int  native_map_set(VmMap* map, const char* key, void* value);

static Value native_map_set(int argCount, Value *args)
{ 

    KeyValuePair *bucket = NULL ;
    int hash = 0;//
    Value map, keyv,valv;
    char* key;

   if(argCount<=2)
    {
       runtime_error("Need 2 argument.");
       return  nil_val() ;
    }
    map=args[0];//map变量
    keyv=args[1];//
    valv=args[2];//
    if(!IS_MAP(map) || !IS_STRING(keyv))
    {
       runtime_error("argument 0 must be map var, argument 1 must be string.");
       return  nil_val() ;
    }
    key=AS_STRING(keyv)->chars;
    
     bucket = map_get_bucket(AS_MAP(map), key);// map_get(map, key);
     if (bucket != NULL) {
         //BUG bucket->value = (void*)&valv;
          bucket->value = (void*)clone(&valv,sizeof(valv)); 
         return bool_val(1);
     }
         return bool_val(0);
 }

//NNative


static VmInterpretResult vm_run()
{
    CallFrame *frame = &vm.frames[vm.frameCount - 1];
#define READ_BYTE() (*frame->ip++)
#define READ_SHORT() (frame->ip += 2, (Short)((frame->ip[-2] << 8) | frame->ip[-1]))
#define READ_CONSTANT() (frame->function->chunk.constants.values[READ_BYTE()])
#define READ_STRING() AS_STRING(READ_CONSTANT())
 


    Short offset;
    Byte instruction, argCount;
    Value arbitraryValue, leftValue, rightValue, *slot = NULL;
    //VmNumber left, right;
    VmInteger leftInt, rightInt;
    VmUInteger leftUInt, rightUInt;
    VmString *name = NULL;
    int strcmp1=0;
    double rightDouble,leftDouble;
     
    for (;;)
    {
#ifdef DEBUG_EXECUTION_TRACE
        printf("    ");
        for (slot = vm.stack; slot < vm.stackTop; slot++)
        {
            printf("[ ");
            value_print(*slot);
            printf(" ]");
        }
        printf("\n");
        chunk_disassemble_instruction(&frame->function->chunk, (int)(frame->ip - frame->function->chunk.code));
#endif
        switch (instruction = READ_BYTE())
        {
        case OP_CONSTANT:
            arbitraryValue = READ_CONSTANT();
            vm_stack_push(arbitraryValue);
            //steven常量定义删除输出
             // value_print(arbitraryValue);
            //bug printf("\n");
            break;
        case OP_NOT:
            arbitraryValue = vm_stack_pop();
            vm_stack_push(bool_val(is_falsey(arbitraryValue)));
            break;
        case OP_NEGATE: //表达式 -N  比如 -2 必须是 整数 /浮点数 ,无符号类型不行 
            //printf("DEBUG4 %d %d " ,IS_NUMBER(vm_stack_peek(0)) ,IS_INT(vm_stack_peek(0)));
            if (!IS_NUMBER(vm_stack_peek(0)) && !IS_INT(vm_stack_peek(0)) )
            {
                 //printf("DEBUG3 ");
                runtime_error("OPerand must be a number");
                return INTERPRET_RUNTIME_ERROR;
            }
           //printf("DEBUG5 ");
            
            //steven 兼容 int
            if (IS_NUMBER(vm_stack_peek(0)))
            {
                //printf("DEBUG1 ");
                arbitraryValue = vm_stack_pop();//必须在这里pop
                vm_stack_push(number_val( - AS_NUMBER(arbitraryValue)));
            }else if(IS_INT(vm_stack_peek(0)))
            {
                //printf("DEBUG2 ");
                 arbitraryValue = vm_stack_pop();//必须在这里pop
               vm_stack_push(integer2_val( - AS_INTEGER(arbitraryValue))); 
            }
            break;
        case OP_ADD:
          //果然是a+b 的右操作数在前面 (下标举例0)
           //printf("DEBUGff %d %d\n ", vm_stack_peek(0).type , vm_stack_peek(1).type );
            //printf("DEBUGff2\n");
             rightValue = vm_stack_peek(0);
             leftValue = vm_stack_peek(1);
            if (IS_STRING(rightValue) && IS_STRING(leftValue))
            {
               //printf("DEBUGff3\n");
                vmstring_concatenate();
            }//steven+
            else if (IS_INT(rightValue) && IS_INT(leftValue))//int+int
            {
               //printf("DEBUGff4\n"); 
                rightInt = AS_INTEGER(vm_stack_pop());
                leftInt = AS_INTEGER(vm_stack_pop());
                vm_stack_push(integer2_val(leftInt + rightInt));
            }
            else if (IS_UINT(rightValue) && IS_UINT(leftValue))//int+int
            {
               //printf("DEBUGff4\n"); 
                rightUInt = AS_UINTEGER(vm_stack_pop());
                leftUInt = AS_UINTEGER(vm_stack_pop());
                vm_stack_push(uinteger2_val(leftUInt + rightUInt));
            }
            //任何一个是double
            else if(
                      ( IS_INT(rightValue) || IS_UINT(rightValue) || IS_NUMBER(rightValue)  )
                 &&   ( IS_INT(leftValue)  || IS_UINT(leftValue)  || IS_NUMBER(leftValue)   )   
               )
            {
              rightValue = vm_stack_pop();
              leftValue = vm_stack_pop();
              if( IS_INT   (rightValue) )  rightDouble = (double)AS_INTEGER (rightValue);
              if( IS_UINT  (rightValue) )  rightDouble = (double)AS_UINTEGER(rightValue );
              if( IS_NUMBER(rightValue) )  rightDouble = (double)AS_NUMBER  (rightValue );
          
              
              if( IS_INT   (leftValue) )  leftDouble = (double)AS_INTEGER (leftValue);
              if( IS_UINT  (leftValue) )  leftDouble = (double)AS_UINTEGER(leftValue);
              if( IS_NUMBER(leftValue) )  leftDouble = (double)AS_NUMBER  (leftValue);
            
             
              //printf("%g %g  %d  %g \n",leftValue,rightValue ,leftDouble>rightDouble ,leftDouble-rightDouble);
               
              vm_stack_push(number_val(leftDouble+rightDouble));                 
            } 
            else
            {
                runtime_error("Operands must be two numbers or two strings.");
                return INTERPRET_RUNTIME_ERROR;
            }
            break;
        case OP_SUBTRACT:  //减法
             rightValue = vm_stack_peek(0);
             leftValue = vm_stack_peek(1);
             // printf(" TYPE %d %d ",leftValue.type, rightValue.type);
             //steven+
            if (IS_INT(rightValue) && IS_INT(leftValue))//int+int
            {
               //printf("DEBUGff4\n"); 
                rightInt = AS_INTEGER(vm_stack_pop());
                leftInt = AS_INTEGER(vm_stack_pop());
                vm_stack_push(integer2_val(leftInt - rightInt));
            }
            else if (IS_UINT(rightValue) && IS_UINT(leftValue))//int+int
            {
               //printf("DEBUGff4\n"); 
                rightUInt = AS_UINTEGER(vm_stack_pop());
                leftUInt = AS_UINTEGER(vm_stack_pop());
                vm_stack_push(uinteger2_val(leftUInt - rightUInt));
            }
            //任何一个是double
            else if(
                      ( IS_INT(rightValue) || IS_UINT(rightValue) || IS_NUMBER(rightValue)  )
                 &&   ( IS_INT(leftValue)  || IS_UINT(leftValue)  || IS_NUMBER(leftValue)   )   
               )
            {
              
              rightValue = vm_stack_pop();
              leftValue = vm_stack_pop();
              if( IS_INT   (rightValue) )  rightDouble = (double)AS_INTEGER (rightValue);
              if( IS_UINT  (rightValue) )  rightDouble =(double) AS_UINTEGER(rightValue );
              if( IS_NUMBER(rightValue) )  rightDouble =(double) AS_NUMBER  (rightValue );
          
              
              if( IS_INT   (leftValue) )  leftDouble = (double)AS_INTEGER (leftValue);
              if( IS_UINT  (leftValue) )  leftDouble = (double)AS_UINTEGER(leftValue);
              if( IS_NUMBER(leftValue) )  leftDouble =(double) AS_NUMBER  (leftValue);
            
             
              //printf("%g %g  %d  %g \n",leftValue,rightValue ,leftDouble>rightDouble ,leftDouble-rightDouble);
               
              vm_stack_push(number_val(leftDouble-rightDouble));                 
            } 
            else
            {
                runtime_error("Operands must be two numbers .");
                return INTERPRET_RUNTIME_ERROR;
            }
            break;
        case OP_MULTIPLY:  //乘法
             rightValue = vm_stack_peek(0);
             leftValue = vm_stack_peek(1);
            //steven+
            if (IS_INT(rightValue) && IS_INT(leftValue))//int+int
            {
               //printf("DEBUGff4\n"); 
                rightInt = AS_INTEGER(vm_stack_pop());
                leftInt = AS_INTEGER(vm_stack_pop());
                vm_stack_push(integer2_val(leftInt * rightInt));
            }
            else if (IS_UINT(rightValue) && IS_UINT(leftValue))//int+int
            {
               //printf("DEBUGff4\n"); 
                rightUInt = AS_UINTEGER(vm_stack_pop());
                leftUInt = AS_UINTEGER(vm_stack_pop());
                vm_stack_push(uinteger2_val(leftUInt* rightUInt));
            }
            //任何一个是double
            else if(
                      ( IS_INT(rightValue) || IS_UINT(rightValue) || IS_NUMBER(rightValue)  )
                 &&   ( IS_INT(leftValue)  || IS_UINT(leftValue)  || IS_NUMBER(leftValue)   )   
               )
            {
              rightValue = vm_stack_pop();
              leftValue = vm_stack_pop();
              if( IS_INT   (rightValue) )  rightDouble = (double)AS_INTEGER (rightValue);
              if( IS_UINT  (rightValue) )  rightDouble =(double) AS_UINTEGER(rightValue );
              if( IS_NUMBER(rightValue) )  rightDouble =(double) AS_NUMBER  (rightValue );
          
              
              if( IS_INT   (leftValue) )  leftDouble = (double)AS_INTEGER (leftValue);
              if( IS_UINT  (leftValue) )  leftDouble = (double)AS_UINTEGER(leftValue);
              if( IS_NUMBER(leftValue) )  leftDouble =(double) AS_NUMBER  (leftValue);
            
             
              //printf("%g %g  %d  %g \n",leftValue,rightValue ,leftDouble>rightDouble ,leftDouble-rightDouble);
               
              vm_stack_push(number_val(leftDouble*rightDouble));                 
            }else 
            {
                runtime_error("Operands must be two numbers .");
                return INTERPRET_RUNTIME_ERROR;
            }
            
            break;
        case OP_DIVIDE:    //除法
            //BINARY_OP(number_val, / );
             //steven+
            //steven+
             rightValue = vm_stack_peek(0);
             leftValue = vm_stack_peek(1);
             if (IS_INT(rightValue) && IS_INT(leftValue))//int+int
            {
               //printf("DEBUGff4\n"); 
                rightInt = AS_INTEGER(vm_stack_pop());
                leftInt = AS_INTEGER(vm_stack_pop());
                vm_stack_push(integer2_val(leftInt- rightInt));
            }
            else if (IS_UINT(rightValue) && IS_UINT(leftValue))//int+int
            {
               //printf("DEBUGff4\n"); 
                rightUInt = AS_UINTEGER(vm_stack_pop());
                leftUInt = AS_UINTEGER(vm_stack_pop());
                vm_stack_push(uinteger2_val(leftUInt - rightUInt));
            }
            //任何一个是double
            else if(
                      ( IS_INT(rightValue) || IS_UINT(rightValue) || IS_NUMBER(rightValue)  )
                 &&   ( IS_INT(leftValue)  || IS_UINT(leftValue)  || IS_NUMBER(leftValue)   )   
               )
            {
              rightValue = vm_stack_pop();
              leftValue = vm_stack_pop();
              if( IS_INT   (rightValue) )  rightDouble =(double) AS_INTEGER (rightValue);
              if( IS_UINT  (rightValue) )  rightDouble =(double) AS_UINTEGER(rightValue );
              if( IS_NUMBER(rightValue) )  rightDouble =(double) AS_NUMBER  (rightValue );
          
              
              if( IS_INT   (leftValue) )  leftDouble = (double)AS_INTEGER (leftValue);
              if( IS_UINT  (leftValue) )  leftDouble =(double) AS_UINTEGER(leftValue);
              if( IS_NUMBER(leftValue) )  leftDouble =(double) AS_NUMBER  (leftValue);
            
             
              //printf("%g %g  %d  %g \n",leftValue,rightValue ,leftDouble>rightDouble ,leftDouble-rightDouble);
               
              vm_stack_push(number_val(leftDouble/rightDouble));                 
            }
            else
            {
                runtime_error("Operands must be two numbers .");
                return INTERPRET_RUNTIME_ERROR;
            }
            break;
            
        case OP_NIL:
            vm_stack_push(nil_val());
            break;
        case OP_TRUE:
            vm_stack_push(bool_val(1));
            break;
        case OP_FALSE:
            vm_stack_push(bool_val(0));
            break;
        case OP_EQUAL:
            rightValue = vm_stack_pop();
            leftValue = vm_stack_pop();
            vm_stack_push(bool_val(values_equal(leftValue, rightValue)));
            break;
        case OP_GREATER:
            //BINARY_OP(bool_val, > );
            rightValue = vm_stack_peek(0);
            leftValue = vm_stack_peek(1);
            //printf("type %d %d    ",leftValue.type, rightValue.type);
            //修改为混合
            if (IS_STRING(leftValue) && IS_STRING(rightValue))
            {
                rightValue = vm_stack_pop();
                leftValue = vm_stack_pop();
                
 
                   //printf("DEBUGff5\n");
                 strcmp1=strcmp(AS_STRING(leftValue )->chars,AS_STRING( rightValue)->chars);//两个字符串比较
                 //strcmp1可能是 相同 =0,s1>s2 ,正数 s1<s2 负数
             
               //printf("DEBUGff6 %d\n" ,strcmp1);
               vm_stack_push(bool_val(strcmp1>0));  
            }//steven>
            else if
               ( (IS_STRING(rightValue) || IS_INT(rightValue) || IS_UINT(rightValue) || IS_NUMBER(rightValue)|| IS_BOOL(rightValue) )
                && (IS_STRING(leftValue)|| IS_INT(leftValue)  || IS_UINT(leftValue)  || IS_NUMBER(leftValue) || IS_BOOL(leftValue) ))
            {
              rightValue = vm_stack_pop();
              leftValue = vm_stack_pop();
			  leftDouble=0;
			  rightDouble=0;
              if( IS_INT   (rightValue) )  rightDouble =(double) AS_INTEGER (rightValue);
              if( IS_UINT  (rightValue) )  rightDouble = (double)AS_UINTEGER(rightValue );
              if( IS_NUMBER(rightValue) )  rightDouble =(double) AS_NUMBER  (rightValue );
              if( IS_BOOL  (rightValue) )  rightDouble =(double) AS_BOOL    (rightValue );
              
              if( IS_INT   (leftValue) )  leftDouble =(double) AS_INTEGER (leftValue);
              if( IS_UINT  (leftValue) )  leftDouble =(double) AS_UINTEGER(leftValue);
              if( IS_NUMBER(leftValue) )  leftDouble = (double)AS_NUMBER  (leftValue);
              if( IS_BOOL  (leftValue) )  leftDouble =(double) AS_BOOL    (leftValue);
             
              //printf("%g %g  %d  %g \n",leftValue,rightValue ,leftDouble>rightDouble ,leftDouble-rightDouble);
               
              vm_stack_push(bool_val(leftDouble>rightDouble));                 
            }else
            {
                runtime_error("Operands must be two numbers or string or bool .");
                return INTERPRET_RUNTIME_ERROR;
            }
           
            break;
        case OP_LESS:
            //BINARY_OP(bool_val, < );
            //修改为混合
            rightValue = vm_stack_peek(0);
            leftValue = vm_stack_peek(1);
            //printf("type %d %d    ",leftValue.type, rightValue.type);
            //修改为混合
            if (IS_STRING(leftValue) && IS_STRING(rightValue))
            {
                rightValue = vm_stack_pop();
                leftValue = vm_stack_pop();
                
 
                   //printf("DEBUGff5\n");
                 strcmp1=strcmp(AS_STRING(leftValue )->chars,AS_STRING( rightValue)->chars);//两个字符串比较
                 //strcmp1可能是 相同 =0,s1>s2 ,正数 s1<s2 负数
             
               //printf("DEBUGff6 %d\n" ,strcmp1);
               vm_stack_push(bool_val(strcmp1>0));  
            }//steven>
            else if
               ( (IS_STRING(rightValue) || IS_INT(rightValue) || IS_UINT(rightValue) || IS_NUMBER(rightValue)|| IS_BOOL(rightValue) )
                && (IS_STRING(leftValue)|| IS_INT(leftValue)  || IS_UINT(leftValue)  || IS_NUMBER(leftValue) || IS_BOOL(leftValue) ))
            {
              rightValue = vm_stack_pop();
              leftValue = vm_stack_pop();
              if( IS_INT   (rightValue) )  rightDouble = (double)AS_INTEGER (rightValue);
              if( IS_UINT  (rightValue) )  rightDouble =(double) AS_UINTEGER(rightValue );
              if( IS_NUMBER(rightValue) )  rightDouble =(double) AS_NUMBER  (rightValue );
              if( IS_BOOL  (rightValue) )  rightDouble =(double) AS_BOOL    (rightValue );
              
              if( IS_INT   (leftValue) )  leftDouble =(double) AS_INTEGER (leftValue);
              if( IS_UINT  (leftValue) )  leftDouble =(double) AS_UINTEGER(leftValue);
              if( IS_NUMBER(leftValue) )  leftDouble =(double) AS_NUMBER  (leftValue);
              if( IS_BOOL  (leftValue) )  leftDouble = (double)AS_BOOL    (leftValue);
             
              //printf("%g %g  %d  %g \n",leftValue,rightValue ,leftDouble>rightDouble ,leftDouble-rightDouble);
               
              vm_stack_push(bool_val(leftDouble<rightDouble));                 
            }else
            {
                runtime_error("Operands must be two numbers or string or bool .");
                return INTERPRET_RUNTIME_ERROR;
            }
            break;
        case OP_RETURN:
            arbitraryValue = vm_stack_pop();

            vm.frameCount--;
            if (vm.frameCount == 0)
            {
                return INTERPRET_OK;
            }

            vm.stackTop = frame->slots;
            vm_stack_push(arbitraryValue);

            frame = &vm.frames[vm.frameCount - 1];
            break;
        case OP_PRINT:
            arbitraryValue = vm_stack_pop();
            //这里是输出 print函数
            value_print(arbitraryValue);
            //bug 这里多余 
            printf("\n");
            break;
        case OP_POP:
            vm_stack_pop();
            break;
        case OP_DEFINE_GLOBAL:
            name = READ_STRING();
            arbitraryValue = vm_stack_peek(0);
            table_set(&vm.globals, name, arbitraryValue);
            vm_stack_pop();
            break;
        case OP_GET_GLOBAL:
            name = READ_STRING();
            if (!table_get(&vm.globals, name, &arbitraryValue))
            {
                runtime_error("Undefined variable at '%s'", name->chars);
                return INTERPRET_RUNTIME_ERROR;
            }
            vm_stack_push(arbitraryValue);
            break;
        case OP_SET_GLOBAL:
            name = READ_STRING();
            if (table_set(&vm.globals, name, vm_stack_peek(0)))
            {
                runtime_error("Undefined variable '%s'.", name->chars);
                return INTERPRET_RUNTIME_ERROR;
            }
            break;
        case OP_GET_LOCAL:
            instruction = READ_BYTE();
            vm_stack_push(frame->slots[instruction]);
            break;
        case OP_SET_LOCAL:
            instruction = READ_BYTE();
            frame->slots[instruction] = vm_stack_peek(0);
            break;
        case OP_JUMP_IF_FALSE:
            offset = READ_SHORT();
            if (is_falsey(vm_stack_peek(0)))
            {
                frame->ip += offset;
            }
            break;
        case OP_JUMP:
            offset = READ_SHORT();
            frame->ip += offset;
            break;
        case OP_LOOP:
            offset = READ_SHORT();
            frame->ip -= offset;
            break;
        case OP_CALL:
            argCount = READ_BYTE();
            if (!value_call(vm_stack_peek(argCount), argCount))
            {
                return INTERPRET_RUNTIME_ERROR;
            }
            frame = &vm.frames[vm.frameCount - 1];
            break;
        default:
            return INTERPRET_COMPILE_ERROR;
        }
    }

#undef READ_BYTE
#undef READ_CONSTANT
#undef READ_SHORT
//#undef BINARY_OP
///#undef BINARY_OP2
}

void vm_init()
{
    vm.objects = NULL;
    vm_stack_reset();
    table_init(&vm.strings);
    table_init(&vm.globals);
    native_define("clock", native_clock);
    //steven注册函数 返回参数是什么类型
    //0 VAL_BOOL  ,
    //1 VAL_NIL   ,
    //2 VAL_INT   ,   ////steven+
    //3 VAL_UINT   ,  ////steven+
    //4 VAL_NUMBER ,
    //5 VAL_OBJECT
    native_define("type", native_type);
    //不同种类类型比较函数
    native_define("equal", native_equal);
    native_define("tostr", native_tostr);
    native_define("ceil", native_ceil);//ceil(value) - 返回一个整数, 不管小数点后面是多少, 整数部分都进1
    
    native_define("abs"        , native_abs        ); //abs(value) - 返回当前数值的绝对值
    native_define("acos"       , native_acos       ); //acos(value) - 返回此角度值的弧余弦值.
    native_define("asin"       , native_asin       ); //asin(value) - 返回此角度值的弧正弦值
    native_define("atan"       , native_atan       ); //atan(value) - 返回此角度值的弧正切值
    native_define("atan2"      , native_atan2      ); //atan2(y, x) - 在角度中, 返回Y/X的弧正切值.
    native_define("cos"        , native_cos        ); //cos(degrees) - 返回角度的余弦值
    native_define("exp"        , native_exp        ); //exp(value) - 返回此值的指数值
    native_define("floor"      , native_floor      ); //floor(value) - 返回此值的整数值
    native_define("log"        , native_log        ); //log(value) - 返回此值的自然对数 (以e为底数)
    native_define("log10"      , native_log10      ); //log10(value) - 返回以10为底数的值
    //native_define("deg"        , native_deg        ); //deg(radians) - 弧度转换角度
    //native_define("rad"        , native_rad        ); //rad(degrees) - 角度转换弧度
    native_define("sin"        , native_sin        ); //sin(degrees) - 返回当前角度的正弦值
    native_define("sqrt"       , native_sqrt       ); //sqrt(value) - 返回数值的平方根值(比如100的平方根为10)
    native_define("tan"        , native_tan        ); //tan(degrees) - 返回当前角度的正切值
    //
    native_define("mod"        , native_mod        ); //mod(value,modulus) - 返回此值的 模数
    native_define("rem"        , native_rem        ); // 余数
    
    ////native_define("random"     , native_random     ); //random([ [lower,] upper]) - 返回一个随机数字 (可选界限为整数值)
    ////native_define("randomseed" , native_randomseed ); //randomseed(seed) - 为伪随机数字生成器设定种子
    ////native_define("frexp"      , native_frexp      ); //frexp(num) - 返回当前数字小数点后的数值以及小数点后的位数 lua是双返回值
    ////native_define("ldexp"      , native_ldexp      ); //ldexp(value, 倍数) - 输出此数值的倍数
    ////native_define("max"        , native_max        ); //max(value[, values...]) - 在一堆值中查找最大值
    ////native_define("min"        , native_min        ); //min(value[,values...]) - 在一堆值中查找最小值
    
    //字符串函数
    native_define("substr"        , native_substr        );
    native_define("leftstr"        , native_leftstr        );
    native_define("rightstr"        , native_rightstr        );
    native_define("strlen"        , native_strlen       );
    native_define("strtoint"        , native_strtoint       );
    native_define("tobinstr"        , native_tobinstr       );
    //数组
    native_define("array"        ,    native_array       );
    native_define("arraylen"        , native_array_len       );
    native_define("arrayset"        , native_array_set      );
    native_define("arrayget"        , native_array_get      );
    //map函数
    native_define("map"                , native_map             );
    native_define("mapadd"            , native_map_add          );
    native_define("mapremove"         , native_map_remove      );
    //native_define("mapdestroy"        , native_map_destroy     );
    native_define("mapget"            , native_map_get         );
    native_define("mapset"            , native_map_set         );
 
    
}

void vm_free()
{
    vm_stack_reset();
    objects_free();
    table_free(&vm.strings);
    table_free(&vm.globals);
}

VmInterpretResult vm_interpret(const char *code)
{
    VmFunction *function = compile(code);
    CallFrame *frame = NULL;

    if (function == NULL)
    {
        return INTERPRET_COMPILE_ERROR;
    }

    vm_stack_push(object_val((VmObject *)function));
    value_call(object_val((VmObject *)function), 0);

    return vm_run();
}